// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System.Linq;
using System.Reflection;

namespace SnapObjects.Data
{
    internal struct MultiDynamicModel : IDynamicModelBase
    {
        internal static readonly ConstructorInfo Constructor
            = typeof(MultiDynamicModel).GetConstructor(new[] { typeof(IDynamicModelBase[]) });

        internal static readonly ConstructorInfo Constructor2
          = typeof(MultiDynamicModel).GetConstructor(new[] { typeof(IDynamicModelBase[]), typeof(object[]) });

        private readonly IDynamicModelBase[] _models;

        public MultiDynamicModel(IDynamicModelBase[] models)
        {
            _models = models;
        }

        public MultiDynamicModel(IDynamicModelBase[] models, object[] values) : this(models)
        {
            this.SetValues(values);
        }

        public T GetValue<T>(int index)
        {
            return _models[index / DynamicModelBaseFactory.MaxGenericTypes].GetValue<T>(index % DynamicModelBaseFactory.MaxGenericTypes);
        }

        public object GetValue(int index)
        {
            return _models[index / DynamicModelBaseFactory.MaxGenericTypes].GetValue(index % DynamicModelBaseFactory.MaxGenericTypes);
        }

        public void SetValue(int index, object value)
        {
            _models[index / DynamicModelBaseFactory.MaxGenericTypes].SetValue(index % DynamicModelBaseFactory.MaxGenericTypes, value);
        }

        public void SetValues(object[] values)
        {
            for (var i = 0; i < values.Length; i += DynamicModelBaseFactory.MaxGenericTypes)
            {
                var arr = values.Skip(i).Take(DynamicModelBaseFactory.MaxGenericTypes).ToArray();

                _models[i / DynamicModelBaseFactory.MaxGenericTypes].SetValues(arr);
            }
        }

        public object this[int index]
        {
            get => _models[index / DynamicModelBaseFactory.MaxGenericTypes][index % DynamicModelBaseFactory.MaxGenericTypes];
            set => _models[index / DynamicModelBaseFactory.MaxGenericTypes][index % DynamicModelBaseFactory.MaxGenericTypes] = value;
        }
    }
}
